<?php

declare(strict_types=1);

namespace Upside\Di;

final class Container implements ContainerInterface
{
    /**
     * @var array<class-string, mixed> $instances
     */
    private array $instances = [];

    /**
     * @var array<class-string, callable(ContainerInterface): mixed> $definitions
     */
    private array $definitions;

    /**
     * @template T
     * @param array<class-string<T>, callable(ContainerInterface): T> $definitions
     */
    public function __construct(array $definitions)
    {
        $this->definitions = $definitions;
    }

    public function get(string $class): mixed
    {
        if (isset($this->instances[$class])) {
            return $this->instances[$class];
        }

        if (isset($this->definitions[$class])) {
            return $this->instances[$class] = $this->definitions[$class]($this);
        }

        throw new ServiceNotFoundException($class);
    }

    public function has(string $class): bool
    {
        return isset($this->instances[$class]);
    }
}
